package string.subStr;

/**
 * @ClassName StrStr
 * @Description TODO
 * @Author lenovo
 * @Date 2023-02-22 17:31
 * @Version 1.0
 * @Comment Magic. Do not touch.
 * If this comment is removed. the program will blow up
 */
public class StrStr {
    /**
     * 实现 strStr() 函数。
     * <p>
     * 给定一个 haystack 字符串和一个 needle 字符串，在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在，则返回  -1。
     * <p>
     * 示例 1: 输入: haystack = "hello", needle = "ll" 输出: 2
     * <p>
     * 示例 2: 输入: haystack = "aaaaa", needle = "bba" 输出: -1
     * <p>
     * 说明: 当 needle 是空字符串时，我们应当返回什么值呢？这是一个在面试中很好的问题。 对于本题而言，当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。
     */

    //第二遍要学习KMP算法
    public int strStr(String haystack, String needle) {
//        int i = 0;
//        int j = 0;
//        int flag = 0;
//
//        while (i < haystack.length() && j < needle.length()) {
//
//            if (haystack.charAt(i) == needle.charAt(j)) {
//                i++;
//                j++;
//                flag++;
//            } else {
//                i++;
//                j = 0;
//                flag = 0;
//            }
//
//            if (j == needle.length() && flag == needle.length()) {
//                return i - needle.length();
//            }
//
//        }
        int h = haystack.length();
        int n = needle.length();
        for (int i = 0; i <= h - n; i++) {
            if (haystack.substring(i, i + n).equals(needle)) {
                return i;
            }
        }

        return -1;

    }

    //暴力算法
    //hello ll
    public int strStr1(String haystack, String needle) {
        int hLen = haystack.length();
        int nLen = needle.length();

        for (int i = 0; i <= hLen - nLen; i++) {
            int j;
            for (j = 0; j < nLen; j++) {
                if (haystack.charAt(i) != needle.charAt(j)) {
                    break;
                }
            }
            if (j == nLen - 1) {
                return i;
            }
        }
        return -1;
    }

    public static void main(String[] args) {
        StrStr strStr = new StrStr();
        //"mississippi"
        //"issip"
//        System.out.println(strStr.strStr1("hello", "ll"));
//        System.out.println(strStr.strStr3("miss", "iss"));
        String needle = "aabaaf";
        int[] next = new int[needle.length()];
        strStr.getNext(next, needle);
        for (int i = 0; i < next.length; i++) {
            System.out.println(next[i]);
        }

        System.out.println(strStr.strStr3("aabaabaafa", "aabaaf"));
//        System.out.println(i);
    }


    //前缀表（不减一）Java实现
    public int strStr3(String haystack, String needle) {

        if (needle.length() == 0) {
            return 0;
        }

        int nLen = needle.length();
        int[] next = new int[needle.length()];

        getNext(next, needle);
        int j = 0;
        for (int i = 0; i < haystack.length(); i++) {
            while (j > 0 && haystack.charAt(i) != needle.charAt(j)) {
                j = next[j - 1];
            }

            if (haystack.charAt(i) == needle.charAt(j)) {
                j++;
            }
            if (j == needle.length()) {
                return i - j + 1;
            }
        }
        return -1;
    }

    private void getNext(int[] next, String needle) {

        next[0] = 0;
        int j = 0;
        for (int i = 1; i < needle.length(); i++) {
            while (j > 0 && needle.charAt(i) != needle.charAt(j)) {
                j = next[j - 1];
            }

            if (needle.charAt(i) == needle.charAt(j)) {
                j++;
            }
            next[i] = j;
        }

    }


}